#include <fstream>
#include "mpp/stream_puller_net.h"
#include "mpp/stream_pusher.h"
#include "base_util/math_compute.h"
#include "osd_text.h"

using namespace stream;

int main(int argc, char** argv) {
  int ret = 0;

  LogInfo* log_ifo = new LogInfo(7, "./log", "log"); 

  StreamPullerInfo puller_ifo;
  // puller_ifo.streamAddress = "rtsp://192.168.0.64:554/media/video1";
  // puller_ifo.streamAddress = "rtsp://2.2.2.65:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1";
  puller_ifo.streamAddress = "rtsp://admin:atcctv@1100@2.2.2.65:554/ch01/main/av_stream";
  puller_ifo.transferType = "tcp";
  puller_ifo.enType = AV_CODEC_ID_H264;  //h264  MPP_VIDEO_CodingAVC
  puller_ifo.vdecChn = 0;
  std::cout<<"puller_ifo.enType:"<<puller_ifo.enType<<std::endl;
  stream::RKStreamPullerNET *puller = new stream::RKStreamPullerNET(&puller_ifo, log_ifo);
  if (ret != (puller->init_params()) != 0) {
    spdlog::get("logger")->info("ERROR puller->init_params error ret:{}\n", ret);
    return ret;
  }
  std::thread(&stream::RKStreamPullerNET::start_pull, puller).detach();


  stream::CVStreamOsdInfo osd_ifo;
  osd_ifo.dstWidth = 1920;
  osd_ifo.dstHeight = 1080;
  osd_ifo.boxThick = 3;
  osd_ifo.boxColorNG = cv::Scalar(0, 0, 255);
  osd_ifo.boxColorOK = cv::Scalar(0, 255, 0);
  osd_ifo.fontHeight = 30;                        

  stream::CVOsdText* osder = new stream::CVOsdText(&osd_ifo, log_ifo);
  if (ret != (osder->init_params()) != 0) {
    spdlog::get("logger")->info("ERROR pusher->init_params error ret:{}\n", ret);
    return ret;
  }


  StreamPusherInfo pusher_ifo;
  pusher_ifo.formatName = "flv";
  pusher_ifo.codecProfile = "main";
  pusher_ifo.fps = 25;
  pusher_ifo.bitrate = 4096;        // Mbps
  pusher_ifo.enType = AV_CODEC_ID_H264;   //MPP_VIDEO_CodingAVC
  pusher_ifo.vEncChn = 0;
  // pusher_ifo.streamAddress = "rtmp://192.168.0.10:9935/push/x3";
  pusher_ifo.streamAddress = "rtmp://127.0.0.1:9935/live/livestream";
  pusher_ifo.dstWidth = puller_ifo.oriWidth;
  pusher_ifo.dstHeight = puller_ifo.oriHeight;

  RKStreamPusher *pusher = new RKStreamPusher(&pusher_ifo, log_ifo);
  if (ret != (pusher->init_params()) != 0) {
    spdlog::get("logger")->info("ERROR pusher->init_params error ret:{}\n", ret);
    return ret;
  }
  std::thread(&RKStreamPusher::start_push, pusher).detach();


  int x = 100;
  int y = 100;
  int cnt = 0;
  stream::ImageBlob buffer(stream::ImageBlobMode_BGR);
  int64_t consume_time = 0;
  int64_t start_time = 0, end_time = 0;
  while(true) {
    std::this_thread::sleep_for(std::chrono::milliseconds(3));
    if ((x + 1200) >= osd_ifo.dstWidth) {x = 100;}
    if (y >= osd_ifo.dstHeight) {y = 100;}
    
    ret = puller->get_frame(buffer);
    if (ret != 0) { continue; }

    std::cout << "bgr_img w:" << buffer.img.cols << " h:" << buffer.img.rows << " c:" << buffer.img.channels() << std::endl;
    start_time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
    std::vector<stream::OSDDrawInfo> osdd_ifos;
    for(int i = 0; i < 9; i++) {
      stream::OSDDrawInfo osdd_ifo;
      // osdd_ifo.texts.push_back("O正确");
      osdd_ifo.texts.push_back("N错误");
      osdd_ifo.x = x + i*150;
      osdd_ifo.y = y;
      osdd_ifo.w = 100;
      osdd_ifo.h = 200;
      osdd_ifos.push_back(osdd_ifo);
    }
    x++;
    y++;
    ret = osder->draw_osd(buffer, osdd_ifos);
    end_time = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
    consume_time += end_time - start_time;
    if (++cnt % 100 == 0) {
      std::cout << "draw_osd: " << consume_time * 1.0 / cnt << std::endl;
      consume_time = 0;
      cnt = 0;
    }

    if (cnt++ % 50 == 0) {
      std::string temp_path = std::to_string(cnt)+".png";
      imwrite(temp_path, buffer.img);
    }

    ret = pusher->add_frame(buffer); 

  }
  return 0;
}


// // 32路拉流测试代码 需要注释掉yuv转rgb部分代码
/*
      err_info = mpp_frame_get_errinfo(frame) | mpp_frame_get_discard(frame);
      if (err_info) { printf("decoder_get_frame get err info:%d discard:%d.\n", mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame)); }
      // ret = copy_buffer(frame,buffer.img,out_buf);
      // if(ret != 0){
      //   printf("copy_buffer failed:%d\n", ret);
      //   goto free;
      // }
    }

    // if (buffer.img.empty()) {goto free;}
    vdec_cnt++;
    // queue_lock.lock();
    // if (queue_data.size() > 3) { queue_data.pop(); }
    // queue_data.push(buffer);
    // queue_lock.unlock();

    if (frm_grp) {
      size_t usage = mpp_buffer_group_usage(frm_grp);
    }
*/
// int main(int argc, char** argv) {
//   int ret = 0;

//   LogInfo* log_ifo = new LogInfo(1, "./log", "log"); 

//   int start_idx = 1001;
//   std::string rtsp_url = "rtsp://2.2.2.110:9554/{0}/1";
//   for (int idx = 0; idx < 32; idx++) {
//     StreamPullerInfo *puller_ifo = new StreamPullerInfo();
//     puller_ifo->streamAddress = util::Format(rtsp_url, std::to_string(start_idx + idx/8)) ;

//     puller_ifo->transferType = "tcp";
//     puller_ifo->enType = AV_CODEC_ID_H264;  //h264  MPP_VIDEO_CodingAVC
//     puller_ifo->vdecChn = idx;
//     std::cout<<"puller_ifo.enType:"<<puller_ifo->enType<<std::endl;
//     stream::RKStreamPullerNET *puller = new stream::RKStreamPullerNET(puller_ifo, log_ifo);
//     if (ret != (puller->init_params()) != 0) {
//       spdlog::get("logger")->info("ERROR puller->init_params error ret:{}\n", ret);
//       return ret;
//     }
//     std::thread(&stream::RKStreamPullerNET::start_pull, puller).detach();
//     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
//   }

//   while (true) {
//     std::this_thread::sleep_for(std::chrono::milliseconds(10));
//   }
//   return 0;
// }



// opencv clone 耗时测试
/*
  cv::Mat rgbImg;
  cv::Mat rgbImg2;
  stream::ImageBlob buffer2(stream::ImageBlobMode_BGR);
  std::queue<stream::ImageBlob> queue_data;

  std::vector<char> content;
  std::string writer_path = argv[1]; 
  std::ifstream infile;
  infile.open(writer_path);
  infile.seekg(0,std::ios::end);//跳转到文件末尾
  long len = infile.tellg();//获取偏移量-文件长度
  infile.seekg(0,std::ios::beg);//跳转到文件起始位置
  content.resize(len);//申请空间
  infile.read(&(content[0]),len);//读取文件数据
  infile.close();//关闭文件

  for (int i = 0 ; i < 10; i++) {
    int64_t time1 = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();;
    buffer2.img = cv::Mat(1080,1920,CV_8UC3,content.data());
    int64_t time2 = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();;

    // rgbImg = bgrImg.clone();
    queue_data.push(buffer2);

    int64_t time3 = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();;
    // rgbImg2 = rgbImg.clone();
    // int64_t time4 = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();;

    // cv::imwrite("./img/bgr.jpg", rgbImg);
    std::cout << "time2-time1: "<< time2 - time1 << ", time3-time2: " << time3 - time2 << std::endl;
    // std::cout << "time4-time3: "<< time4 - time3 << std::endl;
  }

  return 0;

*/